#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;

/*
  ex03 基础概念
    fun01 -基础概念(编译和链接 || 指令,宏定义,库函数,类型定义|| 逻辑运算符)
    fun02 - while循环,for循环,for语句中省略表达式
    fun03 - 函数的补充说明

*/
void fun_01();

int main(){

  if(3 - 3){
    cout << 200 << endl;
  }else{
    cout << false << endl;
  }
  
  fun_01();

  return 0;
}

//fun01 -基础概念(编译和链接 || 指令,宏定义,库函数 || 逻辑运算符)
void fun_01()
{

  //常量 是程序执行过程中不会发生改变的数据，用户可以对其进行命名

  //#include <stdio.h> C语言标准输入/输出库的相关信息。





  /*
    == 编译和链接 ==
    首先，需要生成一个含有上述程序代码名为pun.c的文件（使用任何文本编辑器都可以创建该文件）。
    文件的名字无关紧要，但是编译器通常要求带上文件的扩展名.c。

    要把程序转化为机器可以执行的形式。对于C程序来说，通常包含下列3个步骤。
    1. 预处理。
    首先程序会被送交给预处理器（preprocessor）。预处理器执行以#开头的命令（通常称为指令）。

    2. 编译。
    修改后的程序现在可以进入编译器（compiler）了。
    编译器会把程序翻译成机器指令（即目标代码）。然而，这样的程序还是不可以运行的。

    3.链接。
    在最后一个步骤中，链接器（linker）把由编译器产生的目标代码和所需的其他附加代码整合在一起，这样才最终产生了完全可执行的程序。


    编译器cc有许多选项，其中有一个选项（-o选项）允许为含有可执行程序的文件选择名字。
  */


  /*
    指令（在编译前修改程序的编辑命令）

    所有指令都是以字符#开始的。

    #include <stdio.h>
    这条指令说明，在编译前把<stdio.h>中的信息“包含”到程序中。
  
    <stdio.h> 头（header），每个头都包含一些标准库的内容。


    函数
    数分为两大类：一类是程序员编写的函数，另一类则是作为C语言实现的一部分提供的函数。
    
    我们把后者称为库函数（library function），因为它们属于一个由编译器提供的函数“库”。

    main函数：在执行程序时系统会自动调用main函数。所有程序都只包含一个main函数。
    它会在程序终止时向操作系统返回一个状态码。


    宏定义（macro definition）的特性给常量命名：
    #define INCHES PER POUND 166

    这里的#define是预处理指令
    当对程序进行编译时，预处理器会把每一个宏替换为其表示的值。

    类型定义

    #define指令创建了一个宏，可以用来定义布尔型数据：
    #define BOOL int

    一个更好的设置布尔类型的方法是利用所谓的类型定义（type definition）的特性：
    typedef int Bool; 所定义的类型的名字放在最后。

    采用typedef定义Bool会导致编译器在它所识别的类型名列表中加入Bool。
    现在，Bool类型可以和内置的类型名一样用于变量声明、强制类型转换表达式和其他地方了

    //指针
    typedef int *Item; 相当于 Item 替换为 int *

    typedef int* Item; 
    int a = 30;
    Item pa = &a;
    int *pa = &a;

    typedef struct stack_type * Stack2;


    Bool flag = 0;   //变量flag实际就是一个普通的int类型变量。
  */

  typedef int MBool;
  MBool flag = 300;
  cout << "类型定义: " << flag << endl;
  
  /*

    关系运算符(< , >)的优先级低于算术运算符(+ , -)。

    逻辑运算符的操作如下：
    ·如果表达式的值为0，那么!表达式的结果为1；
    ·如果表达式1和表达式2的值都是非零值，那么表达式1 && 表达式2的结果为1；
    ·如果表达式1或表达式2的值中任意一个是（或者两者都是）非零值，那么表达式1 || 表达式2的结果为1。
    
    在所有其他情况下，这些运算符产生的结果都为0。
  */

}


//fun02 - while循环,for循环,for语句中省略表达式
void fun_02()
{
  /*
        在C语言中，诸如i < j这样的比较运算会产生整数：0（假）或1（真）
  */

 /*
  [while语句]
    while (表达式) 语句
    
    执行while语句时，首先计算控制表达式的值。如果值不为零（即真值），那么执行循环体，接着再次判定表达式。

    这个过程（先判定控制表达式，再执行循环体）持续进行直到控制表达式的值变为零才停止。

    循环体必须是单独的一条语句；如果需要多条语句，那么只要用一对花括号构造成一条复合语句

 */

  /*
  
    [for语句格式]
    for (表达式1; 表达式2; 表达式3) 
    语句其中表达式1、表达式2和表达式3全都是表达式。
  
    for语句非常适合应用在使用“计数”变量的循环中。

    除了一些极少数的情况以外，for循环总可以用等价的while循环替换：

    表达式1
    while(表达式2){
      语句
      表达式3;
    }

    表达式1是循环开始执行前的初始化步骤，只执行一次；
    表达式2用来控制循环的终止（只要表达式2的值不为零，循环持续执行）；
    而表达式3是每次循环中最后被执行的一个操作。

  */

  /*
    在for语句中省略表达式

    即使省略掉某些表达式，控制表达式也必须始终有两个分号
    int j = 0;
    for (;j < bytes.length; ) {
      byte aByte = bytes[j];
      j++;
    }

    如果省略第一个表达式，那么在执行循环前要有初始化的操作。
    如果省略了for语句中的第三个表达式，循环体需要确保第二个表达式的值最终会变为假。

    当for语句同时省略掉第一个和第三个表达式时，它和while语句没有任何分别。


    如果省略第二个表达式，那么它默认为真值，因此for语句不会终止（除非以某种其他形式停止）。


    for (int k = 0; k < bytes.length; k++); // ; 表示一次循环结束
    语句可以为空，也就是除了末尾处的分号以外什么符号也没有。
  */


  /*
    while(i > 0){
      i--;
    }

    可以写成
    while(i){
      i--;
    }

    因为i为0时表示假.

    这样写优点: 简洁
    缺点: 
      新循环可以清楚地显示出在i达到0值时循环终止，但是不能清楚地表示是向上计数还是向下计数。而在原始的循环中，根据控制表达式i > 0可以推断出这一信息。

      其次，如果循环开始执行时i碰巧为负值，那么新循环的行为会不同于原始版本。
  */
}



//fun03 - 函数的补充说明
void fun_03(){

  /*
    函数不能返回数组，但关于返回类型没有其他限制。

    C99遵循这样的规则：在调用一个函数之前，必须先对其进行声明或定义。调用函数时，如果此前编译器未见到该函数的声明或定义，会导致出错。

    C语言允许在实际参数的类型与形式参数的类型不匹配的情况下进行函数调用。
    例如，如果把int类型的实际参数传递给期望得到double类型数据的函数，那么实际参数会被自动转换成double类型。


    C语言没有为函数提供任何简便的方法来确定传递给它的数组的长度；如果函数需要，我们必须把长度作为额外的参数提供出来。

    变长数组形式参数
    在数组参数声明中使用static
    复合字面量

    本书用
    parameter 形参
    argument  实参

    在每个函数定义前放盒型注释可以给出函数名、描述函数的目的、讨论每个形式参数的含义、描述返回值（如果有的话） 并  *** 罗列所有的副作用（如修改了外部变量的值）***。

  */

  //把函数的声明放在另一个函数体内是合法的
  double average(double a,double b);
}

































